package net.cyue.web.easyquery.core.config.json;

import com.fasterxml.jackson.databind.JsonNode;
import net.cyue.util.StreamUtil;
import net.cyue.web.easyquery.core.config.*;
import net.cyue.web.easyquery.core.util.JSONUtil;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

public class EasyQueryJSONConfiguration extends EasyQueryConfiguration {

    public EasyQueryJSONConfiguration() {
        super();
    }

    public static EasyQueryJSONConfiguration fromStream(InputStream inputStream)
        throws IOException, ConfigException
    {
        return fromJSON(StreamUtil.readAsString(inputStream));
    }
    public static EasyQueryJSONConfiguration fromJSON(String json)
        throws ConfigException, IOException
    {
        EasyQueryJSONConfiguration configuration = new EasyQueryJSONConfiguration();
        configuration.readJSONConfiguration(json);
        return configuration;
    }


    public void readJSONConfiguration(InputStream inputStream)
        throws IOException, ConfigException
    {
        this.readJSONConfiguration(StreamUtil.readAsString(inputStream));
    }
    public void readJSONConfiguration(String json)
        throws IOException, ConfigException
    {
        this.configItemValueMap = new HashMap<>();
        JsonNode root = JSONUtil.parse(json);
        if (!root.isObject()) {
            throw new ConfigException("Invalid configuration file");
        }

        // 嵌套 object 款 additional 配置
        // 先读取 key value 的 additional 配置
        AdditionalConfigItem[] additionalConfigItems = this.getAdditionalConfigItems();
        Set<String> additionalConfigItemRootKeySet = new HashSet<>();
        for (AdditionalConfigItem item : additionalConfigItems) {
            String rootKey = item.getGroup().getRoot().getSimpleName();
            String key = item.getFullName();
            String value = JSONUtil.getString(root, key);
            additionalConfigItemRootKeySet.add(rootKey);
            if (value != null) {
                this.configItemValueMap.put(
                    key,
                    ConfigItemValue.fromKeyValue(key, value)
                );
            }
        }

        Iterator<String> fieldNames = root.fieldNames();
        while (fieldNames.hasNext()) {
            String fieldName = fieldNames.next();

            // 跳过 嵌套 object 款 additional 配置
            if (fieldName.equalsIgnoreCase("database")) {
                continue;
            } else if (fieldName.equalsIgnoreCase("server")) {
                continue;
            } else if (fieldName.equalsIgnoreCase("application")) {
                continue;
            } else if (additionalConfigItemRootKeySet.contains(fieldName)) {
                continue;
            }

            JsonNode configItemNode = root.get(fieldName);
            ConfigItemValue configItemValue = JSONConfigItemValue.fromNode(configItemNode);
            this.configItemValueMap.put(fieldName, configItemValue);
        }
    }


}
